home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / gs24src.zip / GDEVXINI.C < prev    next >
C/C++ Source or Header  |  1992-03-18  |  19KB  |  552 lines

  1. /* Copyright (C) 1989, 1992 Aladdin Enterprises.  All rights reserved.
  2.    Distributed by Free Software Foundation, Inc.
  3.  
  4. This file is part of Ghostscript.
  5.  
  6. Ghostscript is distributed in the hope that it will be useful, but
  7. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. to anyone for the consequences of using it or for whether it serves any
  9. particular purpose or works at all, unless he says so in writing.  Refer
  10. to the Ghostscript General Public License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. Ghostscript, but only under the conditions described in the Ghostscript
  14. General Public License.  A copy of this license is supposed to have been
  15. given to you along with Ghostscript so you can know your rights and
  16. responsibilities.  It should be in a file named COPYING.  Among other
  17. things, the copyright notice and this notice must be preserved on all
  18. copies.  */
  19.  
  20. /* gdevxini.c */
  21. /* X Windows driver initialization for Ghostscript library */
  22. #include "gx.h"            /* for gx_bitmap; includes std.h */
  23. #include "memory_.h"
  24. #include "x_.h"
  25. #include "gxdevice.h"
  26. #include "gdevx.h"
  27.  
  28. extern char *getenv(P1(char *));
  29. extern double atof(P1(const char *));
  30.  
  31. /* Define whether to use a backing pixmap to handle expose events. */
  32. /* Note that this is a variable rather than a #define. */
  33. /* Note also that it is consulted each time we open an X device. */
  34. private int use_backing = 1;
  35.  
  36. /* Define default window parameters. */
  37. /* Some of these can be set in the makefile. */
  38.  
  39. #ifndef PROGRAM_NAME
  40. #  define PROGRAM_NAME "Ghostscript"
  41. #endif
  42.  
  43. #define ARG_BORDER_WIDTH "borderWidth"
  44. #define DEFAULT_BORDER_WIDTH 1
  45.  
  46. #define ARG_BORDER_COLOR "borderColor"
  47. #define DEFAULT_BORDER_COLOR  pixel_black
  48.  
  49. #define ARG_GEOMETRY "geometry"
  50.  
  51. #define DEFAULT_X_POSITION 0
  52. #define DEFAULT_Y_POSITION 0
  53.  
  54. #define ARG_X_RESOLUTION "xResolution"
  55. #define ARG_Y_RESOLUTION "yResolution"
  56.  
  57. /* Define constants for orientation from ghostview */
  58. /* Number represents clockwise rotation of the paper in degrees */
  59. typedef enum {
  60.   Portrait = 0,        /* Normal portrait orientation */
  61.   Landscape = 90,    /* Normal landscape orientation */
  62.   Upsidedown = 180,    /* Don't think this will be used much */
  63.   Seascape = 270    /* Landscape rotated the wrong way */
  64. } orientation;
  65.  
  66. /* Open the X device */
  67. int
  68. gdev_x_open(register gx_device_X *xdev)
  69. {       XSizeHints sizehints;
  70.     int border_width;
  71.     char *border_width_str, *border_color_str;
  72.     unsigned long border_color;
  73.     char *geometry;
  74.     char *window_id;
  75.     XColor screen_color, exact_color;
  76.     XSetWindowAttributes xswa;
  77.     XEvent event;
  78.     XVisualInfo xvinfo;
  79.     int nitems;
  80. #if HaveStdCMap
  81.         XStandardColormap *scmap, *sp;
  82.         Atom prop;
  83. #endif
  84. #ifdef DEBUG
  85. if ( gs_debug['X'] )
  86.     { extern int _Xdebug;
  87.       _Xdebug = 1;
  88.     }
  89. #endif
  90.     if ( !(xdev->dpy = XOpenDisplay((char *)NULL)) )
  91.       { char *dispname = getenv("DISPLAY");
  92.         eprintf1("gs: Cannot open X display `%s'.\n",
  93.              (dispname == NULL ? "(null)" : dispname));
  94.         exit(1);
  95.       }
  96. #if HaveStdCMap && defined(sun)
  97.     /* Keep Sun's Dynamic linker happy */
  98.     XtToolkitInitialize();
  99. #endif
  100.     if ( (window_id = getenv("GHOSTVIEW")) )
  101.       { if ( !(xdev->ghostview = sscanf(window_id, "%d %d",
  102.                         &(xdev->win), &(xdev->dest))) )
  103.           { eprintf("gs: Cannot get Window from ghostview.\n");
  104.             exit(1);
  105.           }
  106.       }
  107.     if ( xdev->ghostview )
  108.       { XWindowAttributes attrib;
  109.         Atom type;
  110.         int format;
  111.         unsigned long nitems, bytes_after;
  112.         char *buf;
  113.         Atom ghostview_atom = XInternAtom(xdev->dpy, "GHOSTVIEW", False);
  114.         if ( XGetWindowAttributes(xdev->dpy, xdev->win, &attrib) )
  115.           { xdev->scr = attrib.screen;
  116.             xvinfo.visual = attrib.visual;
  117.         xdev->cmap = attrib.colormap;
  118.             xdev->width = attrib.width;
  119.         xdev->height = attrib.height;
  120.           }
  121.         /* Delete property if explicit dest is given */
  122.         if ( XGetWindowProperty(xdev->dpy, xdev->win, ghostview_atom, 0, 
  123.                     256, (xdev->dest != 0), XA_STRING,
  124.                     &type, &format, &nitems, &bytes_after,
  125.                     (unsigned char **)&buf) == 0 )
  126.           { int llx, lly, urx, ury;
  127.         int left_margin = 0, bottom_margin = 0;
  128.         int right_margin = 0, top_margin = 0;
  129.         orientation page_orientation;
  130.         float xppp, yppp;    /* pixels per point */
  131.         nitems = sscanf(buf,
  132.                 "%d %d %d %d %d %d %f %f %d %d %d %d %d %d",
  133.                         &(xdev->bpixmap), &page_orientation,
  134.                         &llx, &lly, &urx, &ury,
  135.                         &(xdev->x_pixels_per_inch),
  136.                 &(xdev->y_pixels_per_inch),
  137.                 &left_margin, &bottom_margin,
  138.                 &right_margin, &top_margin,
  139.                 &(xdev->width), &(xdev->height));
  140.         if ( (!xdev->dest && !(nitems == 8 || nitems == 12)) ||
  141.              (xdev->dest && nitems != 14) )
  142.           { eprintf("gs: Cannot get ghostview property.\n");
  143.             exit(1);
  144.           }
  145.         if ( xdev->dest && xdev->bpixmap )
  146.           { eprintf("gs: Both destination and backing pixmap specified.\n");
  147.             exit(1);
  148.           }
  149.         xppp = xdev->x_pixels_per_inch / 72.0;
  150.         yppp = xdev->y_pixels_per_inch / 72.0;
  151.         switch (page_orientation)
  152.           {
  153.           case Portrait:
  154.             xdev->initial_matrix.xx = xppp;
  155.             xdev->initial_matrix.xy = 0.0;
  156.             xdev->initial_matrix.yx = 0.0;
  157.             xdev->initial_matrix.yy = -yppp;
  158.             xdev->initial_matrix.tx = -llx * xppp;
  159.             xdev->initial_matrix.ty = ury * yppp;
  160.             break;
  161.           case Landscape:
  162.             xdev->initial_matrix.xx = 0.0;
  163.             xdev->initial_matrix.xy = yppp;
  164.             xdev->initial_matrix.yx = xppp;
  165.             xdev->initial_matrix.yy = 0.0;
  166.             xdev->initial_matrix.tx = -lly * xppp;
  167.             xdev->initial_matrix.ty = -llx * yppp;
  168.             break;
  169.           case Upsidedown:
  170.             xdev->initial_matrix.xx = -xppp;
  171.             xdev->initial_matrix.xy = 0.0;
  172.             xdev->initial_matrix.yx = 0.0;
  173.             xdev->initial_matrix.yy = yppp;
  174.             xdev->initial_matrix.tx = urx * xppp;
  175.             xdev->initial_matrix.ty = -lly * yppp;
  176.             break;
  177.           case Seascape:
  178.             xdev->initial_matrix.xx = 0.0;
  179.             xdev->initial_matrix.xy = -yppp;
  180.             xdev->initial_matrix.yx = -xppp;
  181.             xdev->initial_matrix.yy = 0.0;
  182.             xdev->initial_matrix.tx = ury * xppp;
  183.             xdev->initial_matrix.ty = urx * yppp;
  184.             break;
  185.         }
  186.  
  187.         /* The following sets the imageable area according to the */
  188.         /* bounding box and margins sent by ghostview.            */
  189.         xdev->l_margin = (llx - left_margin) / 72.0;
  190.         xdev->b_margin = (lly - bottom_margin) / 72.0;
  191.         xdev->r_margin = xdev->width / xdev->x_pixels_per_inch -
  192.                  (urx + right_margin) / 72.0;
  193.         xdev->t_margin = xdev->height / xdev->y_pixels_per_inch -
  194.                  (ury + top_margin) / 72.0;
  195.           }
  196.         else
  197.           { eprintf("gs: Cannot get ghostview property.\n");
  198.         exit(1);
  199.           }
  200.       }
  201.     else
  202.       { Screen *scr = DefaultScreenOfDisplay(xdev->dpy);
  203.         xdev->scr = scr;
  204.         xvinfo.visual = DefaultVisualOfScreen(scr);
  205.         xdev->cmap = DefaultColormapOfScreen(scr);
  206.       }
  207.  
  208.     xvinfo.visualid = XVisualIDFromVisual(xvinfo.visual);
  209.     xdev->vinfo = XGetVisualInfo(xdev->dpy, VisualIDMask, &xvinfo, &nitems);
  210.     if ( xdev->vinfo == NULL )
  211.       { eprintf("gs: Cannot get XVisualInfo.\n");
  212.         exit(1);
  213.       }
  214.     xdev->color_info.num_components =
  215.       ((xdev->vinfo->class != StaticGray) &&
  216.        (xdev->vinfo->class != GrayScale) ? 3 : 1);
  217.  
  218. #if HaveStdCMap
  219.     if ( gx_device_has_color(xdev) )
  220.       { if ( xvinfo.visual == DefaultVisualOfScreen(xdev->scr) )
  221.           prop = XA_RGB_DEFAULT_MAP;
  222.         else
  223.           prop = XA_RGB_BEST_MAP;
  224.       }
  225.     else
  226.       prop = XA_RGB_GRAY_MAP;
  227.  
  228.     if ( XGetRGBColormaps(xdev->dpy, RootWindowOfScreen(xdev->scr),
  229.                   &scmap, &nitems, prop) )
  230.       { int i;
  231.         for (i = 0, sp = scmap; i < nitems; i++, sp++)
  232.           { if ( (xdev->ghostview && (xdev->cmap == sp->colormap)) ||
  233.              (!xdev->ghostview && (xdev->vinfo->visualid ==
  234.                         sp->visualid)) )
  235.           { xdev->std_cmap = sp;
  236.             break;
  237.           }
  238.           }
  239.       }
  240.  
  241.     if ( !xdev->std_cmap )
  242.       { if ( XmuLookupStandardColormap(xdev->dpy, DefaultScreen(xdev->dpy),
  243.                        xdev->vinfo->visualid,
  244.                        xdev->vinfo->depth,
  245.                        prop, False, True) )
  246.           { if ( XGetRGBColormaps(xdev->dpy, RootWindowOfScreen(xdev->scr),
  247.                       &scmap, &nitems, prop) )
  248.           { int i;
  249.             for ( i = 0, sp = scmap ; i < nitems ; i++, sp++)
  250.               { if ( (xdev->ghostview && (xdev->cmap ==
  251.                           sp->colormap)) ||
  252.                  (!xdev->ghostview && (xdev->vinfo->visualid ==
  253.                             sp->visualid)) )
  254.               { xdev->std_cmap = sp;
  255.                 break;
  256.               }
  257.               }
  258.           }
  259.           }
  260.       }
  261.     if ( xdev->std_cmap )
  262.       { xdev->cmap = xdev->std_cmap->colormap;
  263.         /* Acquire white and black pixel values. */
  264.         if ( xdev->cmap == DefaultColormapOfScreen(xdev->scr) )
  265.          { pixel_black = BlackPixelOfScreen(xdev->scr);
  266.            pixel_white = WhitePixelOfScreen(xdev->scr);
  267.          }
  268.         else
  269.          {
  270. #define pixv(v)\
  271.   color_index_to_pixel((*xdev->procs->map_rgb_color)((gx_device *)xdev,\
  272.                               v, v, v))
  273.            pixel_black = pixv(0);
  274.            pixel_white = pixv(gx_max_color_value);
  275. #undef pixv
  276.          }
  277.         if ( gx_device_has_color(xdev) )
  278.           { /* Set the color_info in the device structure. */
  279.         xdev->color_info.max_gray =
  280.           xdev->color_info.max_rgb =
  281.             min(xdev->std_cmap->red_max,
  282.             min(xdev->std_cmap->green_max,
  283.                 xdev->std_cmap->blue_max));
  284.         xdev->color_info.depth = 8;    /* arbitrary */
  285.         xdev->color_info.dither_gray =
  286.           xdev->color_info.dither_rgb =
  287.             xdev->color_info.max_rgb + 1;
  288.           }
  289.         else
  290.           { xdev->color_info.max_gray = xdev->std_cmap->red_max +
  291.           xdev->std_cmap->green_max + xdev->std_cmap->blue_max;
  292.         xdev->color_info.depth = 8;    /* arbitrary */
  293.         xdev->color_info.dither_gray = xdev->color_info.max_gray + 1;
  294.           }
  295.       }
  296.     else
  297. #endif
  298.       { if ( xdev->cmap == DefaultColormapOfScreen(xdev->scr) )
  299.           { pixel_black = BlackPixelOfScreen(xdev->scr);
  300.         pixel_white = WhitePixelOfScreen(xdev->scr);
  301.           }
  302.         else
  303.           { XColor xc;
  304.         xc.red = xc.green = xc.blue = 0;
  305.             XAllocColor(xdev->dpy, xdev->cmap, &xc);
  306.         pixel_black = xc.pixel;
  307.         xc.red = xc.green = xc.blue = ~(ushort)0;
  308.             XAllocColor(xdev->dpy, xdev->cmap, &xc);
  309.         pixel_white = xc.pixel;
  310.           }
  311.  
  312.         /* Figure out monochrome vs. color */
  313.         if ( gx_device_has_color(xdev) )
  314.           /* Just do primary colors for now */
  315.           { XColor xc;
  316.         int i;
  317.         for ( i = 1; i < 7; i++ )
  318.           { xc.red = (i & 4 ? ~(ushort)0 : 0);
  319.             xc.green = (i & 2 ? ~(ushort)0 : 0);
  320.             xc.blue = (i & 1 ? ~(ushort)0 : 0);
  321.             XAllocColor(xdev->dpy, xdev->cmap, &xc);
  322.             xdev->colors[i] = xc.pixel;
  323.           }
  324.         xdev->color_info.max_rgb = 1;
  325.         xdev->color_info.dither_rgb = 2;
  326.         xdev->color_info.depth = 8;
  327.           }
  328.         else
  329.           { int i;
  330.             for ( i = 1; i < 7; i++ )
  331.           xdev->colors[i] = pixel_white;
  332.           }
  333.       }
  334.  
  335.     /* Check for a pixel value equal to gx_no_color_index. */
  336.     if (
  337. #if HaveStdCMap
  338.         !xdev->std_cmap &&
  339. #endif
  340.         (pixel_black == gx_no_color_index ||
  341.          pixel_white == gx_no_color_index)
  342.         )
  343.       { /* Pick a non-zero value guaranteed not to map any primary */
  344.         /* color to gx_no_color_index. */
  345.         xdev->pixel_fix = 0x100000ff ^
  346.           (xdev->colors[1] & 2) ^ (xdev->colors[2] & 4) ^
  347.           (xdev->colors[3] & 8) ^ (xdev->colors[4] & 16) ^
  348.           (xdev->colors[5] & 32) ^ (xdev->colors[6] & 64);
  349.       }
  350.     else
  351.       { xdev->pixel_fix = 0;
  352.       }
  353.  
  354.     if ( !xdev->ghostview )
  355.       { /*
  356.          * Figure out the resolution of our screen; 25.4 is the
  357.          * number of millimeters in an inch.  The only reason for
  358.          * allowing the user to specify the resolution is that
  359.          * X servers commonly lie about it (and about the screen size).
  360.          * We assume that the server is more likely to lie about
  361.          * the resolution than about the pixel size of the screen.
  362.          * Don't do any of this if the resolution was set from the
  363.          * command line (detected by resolution != FAKE_RES).
  364.          */
  365.  
  366.         if ( xdev->x_pixels_per_inch == FAKE_RES )
  367.           { char *x_res_str = XGetDefault(xdev->dpy, PROGRAM_NAME,
  368.                           ARG_X_RESOLUTION);
  369.         char *y_res_str = XGetDefault(xdev->dpy, PROGRAM_NAME,
  370.                           ARG_Y_RESOLUTION);
  371.         float x_res, y_res;
  372.         if ( x_res_str != NULL && y_res_str != NULL )
  373.           { x_res = atof(x_res_str);
  374.             y_res = atof(y_res_str);
  375.           }
  376.         else
  377.           { int screen_width = WidthOfScreen(xdev->scr);
  378.             int screen_height = HeightOfScreen(xdev->scr);
  379.             x_res = 25.4 * screen_width / WidthMMOfScreen(xdev->scr);
  380.             y_res = 25.4 * screen_height / HeightMMOfScreen(xdev->scr);
  381.             if ( x_res * DEFAULT_WIDTH_INCHES > screen_width ||
  382.             y_res * DEFAULT_HEIGHT_INCHES > screen_height
  383.             )
  384.               { /* Force a full page to fit on the screen */
  385.             /* by adjusting the server's claimed resolution. */
  386.             x_res = (screen_width - 32) / (float)DEFAULT_WIDTH_INCHES;
  387.             y_res = (screen_height - 32) / (float)DEFAULT_HEIGHT_INCHES;
  388.             x_res = y_res = min(x_res, y_res);
  389.               }
  390.           }
  391.         xdev->x_pixels_per_inch = x_res;
  392.         xdev->y_pixels_per_inch = y_res;
  393.           }
  394.  
  395.         /* Get defaults from the database. */
  396.         border_width_str = XGetDefault(xdev->dpy, PROGRAM_NAME,
  397.                        ARG_BORDER_WIDTH);
  398.  
  399.         border_width = (border_width_str == NULL ? DEFAULT_BORDER_WIDTH :
  400.                 atoi(border_width_str));
  401.  
  402.         border_color_str = XGetDefault(xdev->dpy, PROGRAM_NAME,
  403.                        ARG_BORDER_COLOR);
  404.  
  405.         border_color = (border_color_str == NULL ||
  406.                  !XAllocNamedColor(xdev->dpy, xdev->cmap, 
  407.                            border_color_str, 
  408.                            &screen_color, &exact_color) ?
  409.                 DEFAULT_BORDER_COLOR :
  410.                 screen_color.pixel);
  411.  
  412.         sizehints.x = DEFAULT_X_POSITION;
  413.         sizehints.y = DEFAULT_Y_POSITION;
  414.         sizehints.width =
  415.                   (int)(xdev->x_pixels_per_inch * DEFAULT_WIDTH_INCHES);
  416.         sizehints.height =
  417.                   (int)(xdev->y_pixels_per_inch * DEFAULT_HEIGHT_INCHES);
  418.         sizehints.flags = 0;
  419.  
  420.         geometry = XGetDefault(xdev->dpy, PROGRAM_NAME, ARG_GEOMETRY);
  421.  
  422.         if (geometry != NULL)
  423.            {    /*
  424.              * Note that border_width must be set first.  We can't use
  425.              * scr, because that is a Screen*, and XGeometry wants
  426.              * the screen number.
  427.              */
  428.             char gstr[40];
  429.             int bitmask;
  430.             sprintf(gstr, "%dx%d+%d+%d", sizehints.width,
  431.                 sizehints.height, sizehints.x, sizehints.y);
  432.             bitmask = XGeometry(xdev->dpy, DefaultScreen(xdev->dpy),
  433.                     geometry, gstr, border_width,
  434.                     1, 1, /* ``Font'' width and height. */
  435.                     0, 0, /* Interior padding. */
  436.                     &sizehints.x, &sizehints.y,
  437.                     &sizehints.width, &sizehints.height);
  438.  
  439.             if (bitmask & (XValue | YValue))
  440.                 sizehints.flags |= USPosition;
  441.  
  442.             if (bitmask & (WidthValue | HeightValue))
  443.                 sizehints.flags |= USSize;
  444.            }
  445.  
  446.         if ( xdev->width == (int)(FAKE_RES*DEFAULT_WIDTH_INCHES) )
  447.           xdev->width = sizehints.width,
  448.           xdev->height = sizehints.height;
  449.         else            /* set from command line */
  450.           sizehints.width = xdev->width,
  451.           sizehints.height = xdev->height;
  452.  
  453.         gx_default_get_initial_matrix((gx_device *)xdev,
  454.                       &(xdev->initial_matrix));
  455.  
  456.         xswa.event_mask = ExposureMask;
  457.         xswa.background_pixel = pixel_black;
  458.         xswa.border_pixel = border_color;
  459.         xswa.colormap = xdev->cmap;
  460.         xdev->win = XCreateWindow(xdev->dpy, RootWindowOfScreen(xdev->scr),
  461.                       sizehints.x, sizehints.y, /* upper left */
  462.                       sizehints.width, sizehints.height,
  463.                       border_width,
  464.                       xdev->vinfo->depth,
  465.                       InputOutput, /* class */
  466.                       xdev->vinfo->visual, /* visual */
  467.                       CWEventMask | CWBackPixel |
  468.                       CWBorderPixel | CWColormap,
  469.                       &xswa);
  470.         XChangeProperty(xdev->dpy, xdev->win, XA_WM_NAME, XA_STRING, 8,
  471.                 PropModeReplace, (unsigned char *)PROGRAM_NAME,
  472.                 strlen(PROGRAM_NAME));
  473.         XSetNormalHints(xdev->dpy, xdev->win, &sizehints);
  474.        
  475.         if ( use_backing )
  476.           xdev->bpixmap =
  477.             XCreatePixmap(xdev->dpy, xdev->win,
  478.                   xdev->width, xdev->height,
  479.                   xdev->vinfo->depth);
  480.         else
  481.           xdev->bpixmap = (Pixmap)0;
  482.     }
  483.  
  484.     xdev->ht.pixmap = (Pixmap)0;
  485.     xdev->ht.id = gx_no_bitmap_id;;
  486.     xdev->fill_style = FillSolid;
  487.     xdev->function = GXcopy;
  488.  
  489.     /* Set up a graphics context */
  490.     xdev->gc = XCreateGC(xdev->dpy, xdev->win, 0, (XGCValues *)NULL);
  491.     XSetFunction(xdev->dpy, xdev->gc, GXcopy);
  492.     XSetLineAttributes(xdev->dpy, xdev->gc, 0,
  493.                LineSolid, CapButt, JoinMiter);
  494.  
  495.     /* Clear the destination pixmap to avoid initializing with garbage. */
  496.     if ( xdev->dest != (Pixmap)0 )
  497.       { XSetForeground(xdev->dpy, xdev->gc, pixel_white);
  498.         XFillRectangle(xdev->dpy, xdev->dest, xdev->gc,
  499.                0, 0, xdev->width, xdev->height);
  500.       }
  501.     else
  502.       { xdev->dest = (xdev->bpixmap != (Pixmap)0 ?
  503.               xdev->bpixmap : (Pixmap)xdev->win);
  504.       }
  505.  
  506.     /* Clear the background pixmap to avoid initializing with garbage. */
  507.     if ( xdev->bpixmap != (Pixmap)0 )
  508.       { if ( !xdev->ghostview )
  509.           XSetWindowBackgroundPixmap(xdev->dpy, xdev->win, xdev->bpixmap);
  510.         XSetForeground(xdev->dpy, xdev->gc, pixel_white);
  511.         XFillRectangle(xdev->dpy, xdev->bpixmap, xdev->gc,
  512.                0, 0, xdev->width, xdev->height);
  513.       }
  514.  
  515.     /* Initialize foreground and background colors */
  516.     xdev->back_color = pixel_white;
  517.     XSetBackground(xdev->dpy, xdev->gc, pixel_white);
  518.     xdev->fore_color = pixel_white;
  519.     XSetForeground(xdev->dpy, xdev->gc, pixel_white);
  520.     xdev->colors_or = xdev->colors_and = pixel_white;
  521.  
  522.     if ( !xdev->ghostview )
  523.       { /* Make the window appear. */
  524.         XMapWindow(xdev->dpy, xdev->win);
  525.  
  526.         /* Before anything else, do a flush and wait for */
  527.         /* an exposure event. */
  528.         XFlush(xdev->dpy);
  529.         XNextEvent(xdev->dpy, &event);
  530.       }
  531.     else
  532.       { /* Create an unmapped window, that the window manager will ignore.
  533.          * This invisble window will be used to receive "next page"
  534.          * events from ghostview */
  535.         XSetWindowAttributes attributes;
  536.         attributes.override_redirect = True;
  537.         xdev->mwin = XCreateWindow(xdev->dpy, RootWindowOfScreen(xdev->scr),
  538.                        0, 0, 1, 1, 0, CopyFromParent,
  539.                        CopyFromParent, CopyFromParent,
  540.                        CWOverrideRedirect, &attributes);
  541.         xdev->next = XInternAtom(xdev->dpy, "NEXT", False);
  542.         xdev->page = XInternAtom(xdev->dpy, "PAGE", False);
  543.         xdev->done = XInternAtom(xdev->dpy, "DONE", False);
  544.       }
  545.  
  546.     xdev->ht.no_pixmap = XCreatePixmap(xdev->dpy, xdev->win, 1, 1,
  547.                        xdev->vinfo->depth);
  548.  
  549.     XSync(xdev->dpy, 0);
  550.     return 0;
  551. }
  552.